﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;

namespace DIProject.Data
{
    /// <summary>
    /// пробиваем на кассе 1 чек
    /// </summary>
    public class Cash
    {
        //private SqlTransaction _tracsaction;
        private DateTime _docMd = new DateTime(1900, 1, 1);
        private Int32 _docId = Int32.MinValue;
        private Cash()
        { }
        public Int32 DocId
        {
            get
            {
                return _docId;
            }            
        }
        public DateTime MD
        {
            get
            {
                return _docMd;
            }
        }
        private int _cashDocId;

        public int CashDocId
        {
            get { return _cashDocId; }
            set { _cashDocId = value; }
        }

        string _conString;
        public Cash(string connectionString)
        {
            _conString = connectionString;
        }   
        private bool isDocCreate = false;
        public Int32 CreateNewDoc
            (DateTime docDate, 
            Int32 docNumber, 
            Int32 cashRegisterShiftId,
            Int32? departmentUserId,
            string note,
            DateTime md,
            string mw
            )
        {
            //вызвать можем только 1 раз
            if (isDocCreate)
                throw new Exception("Документ уже создан");
            isDocCreate = true;
            string QueryString = @"dbo.CashRegisterDocInsert";
            SqlDataReader r=null;
            try
            {
                using (SqlConnection connection = new SqlConnection(this._conString))
                {
                    SqlCommand command = new SqlCommand(QueryString, connection);
                    connection.Open();
                    command.CommandType = CommandType.StoredProcedure;
                    SqlParameter dDate = new SqlParameter("@DocDate", SqlDbType.SmallDateTime);
                    dDate.Value = docDate;
                    command.Parameters.Add(dDate);
                    SqlParameter dNumber = new SqlParameter("@DocNumber", SqlDbType.Int);
                    dNumber.Value = docNumber;
                    command.Parameters.Add(dNumber);
                    SqlParameter cRegisterShiftId = new SqlParameter("@CashRegisterShiftId", SqlDbType.Int);
                    cRegisterShiftId.Value = cashRegisterShiftId;
                    command.Parameters.Add(cRegisterShiftId);
                    SqlParameter dUserId = new SqlParameter("@DepartmentUserId", SqlDbType.Int);
                    if (departmentUserId.HasValue)
                        dUserId.Value = departmentUserId;
                    else
                        dUserId.Value = DBNull.Value;
                    command.Parameters.Add(dUserId);
                    SqlParameter n = new SqlParameter("@Note", SqlDbType.VarChar, 250);
                    n.Value = string.Empty;
                    command.Parameters.Add(n);
                    SqlParameter _md = new SqlParameter("@MD", SqlDbType.DateTime);
                    _md.Value = md;
                    command.Parameters.Add(_md);
                    SqlParameter _mw = new SqlParameter("@MW", SqlDbType.VarChar, 50);
                    _mw.Value = mw;
                    command.Parameters.Add(_mw);
                    r = command.ExecuteReader();
                    if (!r.Read())
                    {
                        throw new Exception("Не удалось создать документ в БД");
                    }
                    Int32 tmp = r.GetOrdinal("Id");
                    Int32 tmp2 = r.GetOrdinal("MD");
                    if (r.IsDBNull(tmp))
                    {
                        throw new Exception("Не удалось создать документ в БД");
                    }
                    if (r.IsDBNull(tmp2))
                    {
                        throw new Exception("Не удалось создать документ в БД");
                    }
                    _docId = Convert.ToInt32(r[tmp]);
                    _docMd = Convert.ToDateTime(r[tmp2]);
                    return _docId;
                }

            }
            catch (SqlException se)
            {
                this.Rollback();
                throw new DIProject.Util.DIException("Ошибка", se);
            }
            catch (Exception e)
            {
                this.Rollback();
                throw new DIProject.Util.DIException("Ошибка", e);
            }   
        }
        public Int32 CreateNewDoc2
            (DateTime docDate,
            Int32 docNumber,
            Int32 cashRegisterShiftId,
            Int32? departmentUserId,
        //    @SaleDiscountTypesId int, --тип скидки
//	@СashlessPayment bit,	--признак безналичной оплаты 0-наличная, 1-безналичная
            Int32 saleDiscountTypesId,
            bool cashlessPayment,
            string note,
            DateTime md,
            string mw
            )
        {
            //вызвать можем только 1 раз
            if (isDocCreate)
                throw new Exception("Документ уже создан");
            isDocCreate = true;
            string QueryString = @"dbo.CashRegisterDocInsert";
            SqlDataReader r = null;
            try
            {
                using (SqlConnection connection = new SqlConnection(this._conString))
                {
                    SqlCommand command = new SqlCommand(QueryString, connection);
                    connection.Open();
                    command.CommandType = CommandType.StoredProcedure;
                    SqlParameter dDate = new SqlParameter("@DocDate", SqlDbType.SmallDateTime);
                    dDate.Value = docDate;
                    command.Parameters.Add(dDate);
                    SqlParameter dNumber = new SqlParameter("@DocNumber", SqlDbType.Int);
                    dNumber.Value = docNumber;
                    command.Parameters.Add(dNumber);
                    SqlParameter cRegisterShiftId = new SqlParameter("@CashRegisterShiftId", SqlDbType.Int);
                    cRegisterShiftId.Value = cashRegisterShiftId;
                    command.Parameters.Add(cRegisterShiftId);
                    SqlParameter dUserId = new SqlParameter("@DepartmentUserId", SqlDbType.Int);
                    if (departmentUserId.HasValue)
                        dUserId.Value = departmentUserId;
                    else
                        dUserId.Value = DBNull.Value;
                    command.Parameters.Add(dUserId);
                    SqlParameter PsaleDiscountTypesId = new SqlParameter("@SaleDiscountTypesId", SqlDbType.Int);
                    PsaleDiscountTypesId.Value = saleDiscountTypesId;
                    command.Parameters.Add(PsaleDiscountTypesId);
                    SqlParameter PcashlessPayment = new SqlParameter("@СashlessPayment", SqlDbType.Bit);
                    PcashlessPayment.Value = cashlessPayment;
                    command.Parameters.Add(PcashlessPayment);
                    SqlParameter n = new SqlParameter("@Note", SqlDbType.VarChar, 250);
                    n.Value = string.Empty;
                    command.Parameters.Add(n);
                    SqlParameter _md = new SqlParameter("@MD", SqlDbType.DateTime);
                    _md.Value = md;
                    command.Parameters.Add(_md);
                    SqlParameter _mw = new SqlParameter("@MW", SqlDbType.VarChar, 50);
                    _mw.Value = mw;
                    command.Parameters.Add(_mw);
                    r = command.ExecuteReader();
                    if (!r.Read())
                    {
                        throw new Exception("Не удалось создать документ в БД");
                    }
                    Int32 tmp = r.GetOrdinal("Id");
                    Int32 tmp2 = r.GetOrdinal("MD");
                    if (r.IsDBNull(tmp))
                    {
                        throw new Exception("Не удалось создать документ в БД");
                    }
                    if (r.IsDBNull(tmp2))
                    {
                        throw new Exception("Не удалось создать документ в БД");
                    }
                    _docId = Convert.ToInt32(r[tmp]);
                    _docMd = Convert.ToDateTime(r[tmp2]);
                    return _docId;
                }

            }
            catch (SqlException se)
            {
                this.Rollback();
                throw new DIProject.Util.DIException("Ошибка", se);
            }
            catch (Exception e)
            {
                this.Rollback();
                throw new DIProject.Util.DIException("Ошибка", e);
            }
        }
        /// <summary>
        /// записываем в базу 1 товар с кассы
        /// </summary>
        /// <param name="docId"></param>
        /// <param name="partyId"></param>
        /// <param name="qntty"></param>
        /// <param name="retailSum"></param>
        /// <param name="note"></param>
        /// <param name="md"></param>
        /// <param name="mw"></param>
        /// <returns></returns>
        public Int32 InsertNewLine
            (Int32 docId, 
            Int32 partyId, 
            Int32 qntty, 
            decimal retailSum, 
            string note, 
            DateTime md, 
            string mw)
        {
            string QueryString = @"dbo.CashRegisterLinesInsert";
            SqlDataReader r = null;
            try
            {
                using (SqlConnection connection = new SqlConnection(this._conString))
                {
                    SqlCommand command = new SqlCommand(QueryString, connection);
                    command.CommandType = CommandType.StoredProcedure;
                    connection.Open();
                    SqlParameter dId = new SqlParameter("@DocId", SqlDbType.Int);
                    dId.Value = docId;
                    command.Parameters.Add(dId);
                    SqlParameter pId = new SqlParameter("@PartyId", SqlDbType.Int);
                    pId.Value = partyId;
                    command.Parameters.Add(pId);
                    SqlParameter q = new SqlParameter("@Qntty", SqlDbType.Int);
                    q.Value = qntty;
                    command.Parameters.Add(q);
                    SqlParameter rSum = new SqlParameter("@RetailSum", SqlDbType.Decimal);
                    rSum.Value = retailSum;
                    command.Parameters.Add(rSum);
                    SqlParameter n = new SqlParameter("@Note", SqlDbType.VarChar, 250);
                    n.Value = note;
                    command.Parameters.Add(n);
                    SqlParameter _md = new SqlParameter("@MD", SqlDbType.DateTime);
                    _md.Value = md;
                    command.Parameters.Add(_md);
                    SqlParameter _mw = new SqlParameter("@MW", SqlDbType.VarChar, 50);
                    _mw.Value = mw;
                    command.Parameters.Add(_mw);
                    r = command.ExecuteReader();
                    if (!r.Read())
                    {
                        throw new Exception("Не удалось создать строку чека в БД\t" + " партия " + partyId.ToString());
                    }
                    Int32 tmp = r.GetOrdinal("Id");
                    if (r.IsDBNull(tmp))
                    {
                        throw new Exception("Не удалось создать строку чека в БД\t" + " партия " + partyId.ToString());
                    }
                    Int32 result = Convert.ToInt32(r[tmp]);
                    return result;
                }
            }
            catch (SqlException se)
            {
                Rollback();
                throw new Exception("",se);
            }
            catch (Exception e)
            {
                Rollback();
                throw new Exception("", e);
            }   
        }
        public Int32 InsertNewLine2
            (Int32 docId,
            Int32 partyId,
            Int32 qntty,
            decimal retailSum,
            //@DiscountValue tinyint
            byte discountValue,
            string note,
            DateTime md,
            string mw)
        {
            string QueryString = @"dbo.CashRegisterLinesInsert";
            SqlDataReader r = null;
            try
            {
                using (SqlConnection connection = new SqlConnection(this._conString))
                {
                    SqlCommand command = new SqlCommand(QueryString, connection);
                    command.CommandType = CommandType.StoredProcedure;
                    connection.Open();
                    SqlParameter dId = new SqlParameter("@DocId", SqlDbType.Int);
                    dId.Value = docId;
                    command.Parameters.Add(dId);
                    SqlParameter pId = new SqlParameter("@PartyId", SqlDbType.Int);
                    pId.Value = partyId;
                    command.Parameters.Add(pId);
                    SqlParameter q = new SqlParameter("@Qntty", SqlDbType.Int);
                    q.Value = qntty;
                    command.Parameters.Add(q);
                    SqlParameter rSum = new SqlParameter("@RetailSum", SqlDbType.Decimal);
                    rSum.Value = retailSum;
                    command.Parameters.Add(rSum);
                    SqlParameter pdiscountValue = new SqlParameter("@DiscountValue", SqlDbType.TinyInt);
                    pdiscountValue.Value = discountValue;
                    command.Parameters.Add(pdiscountValue);
                    SqlParameter n = new SqlParameter("@Note", SqlDbType.VarChar, 250);
                    n.Value = note;
                    command.Parameters.Add(n);
                    SqlParameter _md = new SqlParameter("@MD", SqlDbType.DateTime);
                    _md.Value = md;
                    command.Parameters.Add(_md);
                    SqlParameter _mw = new SqlParameter("@MW", SqlDbType.VarChar, 50);
                    _mw.Value = mw;
                    command.Parameters.Add(_mw);
                    r = command.ExecuteReader();
                    if (!r.Read())
                    {
                        throw new Exception("Не удалось создать строку чека в БД\t" + " партия " + partyId.ToString());
                    }
                    Int32 tmp = r.GetOrdinal("Id");
                    if (r.IsDBNull(tmp))
                    {
                        throw new Exception("Не удалось создать строку чека в БД\t" + " партия " + partyId.ToString());
                    }
                    Int32 result = Convert.ToInt32(r[tmp]);
                    return result;
                }
            }
            catch (SqlException se)
            {
                Rollback();
                throw new Exception("", se);
            }
            catch (Exception e)
            {
                Rollback();
                throw new Exception("", e);
            }
        }       
        public void Rollback()
        {
            try
            {
                InnerRollback();
                Util.DILogInFile.LogDBCancelDoc(this._docMd, this.CashDocId);
            }
            catch (Exception ee)
            {
                throw new Exception("Внутрення ошибка. Возможны данные в базе данных не будут соответсвовать данным на фескальном регистраторе", ee);
            }
        }
        /// <summary>
        /// удаляем документ
        /// </summary>
        private void InnerRollback()
        {
            if (this._docId == Int32.MinValue)
                return;
            DateTime tmp = new DateTime(1900,1,1);
            if (this._docMd == tmp)
                return;
            string QueryString = "dbo.CashRegisterDocDelete";            
            try
            {
                /*
                 @Original_Id int,
	             @Original_MD datetime
                 */
                using (SqlConnection connection = new SqlConnection(_conString))
                {
                    SqlCommand command = new SqlCommand(QueryString, connection);
                    command.CommandType = CommandType.StoredProcedure;
                    connection.Open();
                    SqlParameter id = new SqlParameter("@Original_Id", SqlDbType.Int);
                    id.Value = this._docId;
                    command.Parameters.Add(id);
                    SqlParameter md = new SqlParameter("@Original_MD", SqlDbType.DateTime);
                    md.Value = this._docMd;
                    command.Parameters.Add(md);
                    command.ExecuteNonQuery();
                }
            }
            catch (SqlException se)
            {
                throw new Exception("Ошибка при удаленнии документа", se);
            }
            catch (Exception ee)
            {
                throw new Exception("Ошибка при удаленнии документа", ee);
            }
        }
    }
}
